package com.ruoyi.app.service.impl

import cn.hutool.core.bean.BeanUtil
import com.alipay.easysdk.factory.Factory
import com.alipay.easysdk.kernel.util.ResponseChecker
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest
import com.github.binarywang.wxpay.service.WxPayService
import com.ruoyi.app.common.*
import com.ruoyi.app.service.PayApiService
import com.ruoyi.back.domain.dto.CartoonOrderDto
import com.ruoyi.back.domain.dto.Pic2PicOrderDto
import com.ruoyi.back.domain.dto.Text2PicOrderDto
import com.ruoyi.back.domain.dto.UserMemberOrderDto
import com.ruoyi.back.domain.v3.SinglePayRecord
import com.ruoyi.back.domain.v3.SinglePayRecordService
import com.ruoyi.back.enums.PayTypeEnum
import com.ruoyi.back.service.MemberService
import com.ruoyi.back.service.UserMemberOrderService
import com.ruoyi.back.service.UserMemberService
import com.ruoyi.common.utils.ip.IpUtils
import com.ruoyi.config.PayNotifyParam
import io.swagger.annotations.ApiModelProperty
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.stereotype.Service
import javax.servlet.http.HttpServletRequest

@Service
@EnableConfigurationProperties(PayNotifyParam::class)
class PayApiServiceImpl : PayApiService {

    private final val log = LoggerFactory.getLogger(PayApiServiceImpl::class.java)

    @Autowired
    private lateinit var wxService: WxPayService

    @Autowired
    private lateinit var userMemberOrderService: UserMemberOrderService

    @Autowired
    private lateinit var memberService: MemberService

    @Autowired
    private lateinit var userMemberService: UserMemberService

    @Autowired
    private lateinit var payNotifyParam: PayNotifyParam

    @Autowired
    private lateinit var singlePayRecordService: SinglePayRecordService

    override fun <T> createWxOrder(userMemberOrderDto: UserMemberOrderDto): Data<T> =
        Ok("创建微信预支付成功",
            userMemberOrderService.createUserMemberOrder(userMemberOrderDto.apply {
                payType = PayTypeEnum.WEI_XIN.code
            })
                .let {
                    this.wxService.createOrder(WxPayUnifiedOrderRequest().apply {
                        body = memberService.getNameByMemberId(it.memberId!!)
                        totalFee = it.payAmount?.fen()
                        notifyUrl = "http://aipic.hfyanlv.com/aipic-api/api/pay/wxNotify"
                        outTradeNo = it.orderNum
                        spbillCreateIp = IpUtils.getHostIp()
                        tradeType = "APP"
                    })
                }
        )

    override fun <T> createText2PicOrder(text2PicOrderDto: Text2PicOrderDto): Data<T> {

        val singlePayRecord = SinglePayRecord()
        singlePayRecordService.save(singlePayRecord.apply {
            type = 1
            text = text2PicOrderDto.text
            resolution = text2PicOrderDto.resolution
            style = text2PicOrderDto.style
            num = text2PicOrderDto.num
        })
        return Ok("创建文生图预支付成功",
            userMemberOrderService.createUserMemberOrder(UserMemberOrderDto().apply {
                BeanUtil.copyProperties(text2PicOrderDto, this)
                payType = PayTypeEnum.WEI_XIN.code
                singlePayRecordId = singlePayRecord.id
            }).let {
                    this.wxService.createOrder(WxPayUnifiedOrderRequest().apply {
                        body = memberService.getNameByMemberId(it.memberId!!)
                        totalFee = it.payAmount?.fen()
                        notifyUrl = "http://aipic.hfyanlv.com/aipic-api/api/pay/wxNotify"
                        outTradeNo = it.orderNum
                        spbillCreateIp = IpUtils.getHostIp()
                        tradeType = "APP"
                    })
                }
        )
    }

    override fun <T> createPic2PicOrder(pic2PicOrderDto: Pic2PicOrderDto): Data<T> {
        val singlePayRecord = SinglePayRecord()
        singlePayRecordService.save(singlePayRecord.apply {
            type = 2
            inputUrl = pic2PicOrderDto.inputUrl
            prompt = pic2PicOrderDto.prompt
            negativePrompt = pic2PicOrderDto.negativePrompt
            style = pic2PicOrderDto.styles
            resultConfig = pic2PicOrderDto.resultConfig
            strength = pic2PicOrderDto.strength
        })
        return Ok("创建图生图预支付成功",
            userMemberOrderService.createUserMemberOrder(UserMemberOrderDto().apply {
                BeanUtil.copyProperties(pic2PicOrderDto, this)
                payType = PayTypeEnum.WEI_XIN.code
                singlePayRecordId = singlePayRecord.id
            }).let {
                this.wxService.createOrder(WxPayUnifiedOrderRequest().apply {
                    body = memberService.getNameByMemberId(it.memberId!!)
                    totalFee = it.payAmount?.fen()
                    notifyUrl = "http://aipic.hfyanlv.com/aipic-api/api/pay/wxNotify"
                    outTradeNo = it.orderNum
                    spbillCreateIp = IpUtils.getHostIp()
                    tradeType = "APP"
                })
            }
        )
    }

    override fun <T> createCartoonOrder(cartoonOrderDto: CartoonOrderDto): Data<T> {
        val singlePayRecord = SinglePayRecord()
        singlePayRecordService.save(singlePayRecord.apply {
            type = 3
            style = cartoonOrderDto.style
            inputUrl = cartoonOrderDto.inputUrl
        })
        return Ok("创建图生图预支付成功",
            userMemberOrderService.createUserMemberOrder(UserMemberOrderDto().apply {
                BeanUtil.copyProperties(cartoonOrderDto, this)
                payType = PayTypeEnum.WEI_XIN.code
                singlePayRecordId = singlePayRecord.id
            }).let {
                this.wxService.createOrder(WxPayUnifiedOrderRequest().apply {
                    body = memberService.getNameByMemberId(it.memberId!!)
                    totalFee = it.payAmount?.fen()
                    notifyUrl = "http://aipic.hfyanlv.com/aipic-api/api/pay/wxNotify"
                    outTradeNo = it.orderNum
                    spbillCreateIp = IpUtils.getHostIp()
                    tradeType = "APP"
                })
            }
        )
    }

    override fun createAliOrder(userMemberOrderDto: UserMemberOrderDto): Data<String> =
        userMemberOrderService.createUserMemberOrder(userMemberOrderDto.apply { payType = PayTypeEnum.ALI_PAY.code })
            .let {
                Factory.Payment.App().pay(
                    memberService.getNameByMemberId(it.memberId!!),
                    it.orderNum,
                    memberService.getById(userMemberOrderDto.memberId)?.price.toString()
                )
                    .takeIf { alipayTradeAppPayResponse -> ResponseChecker.success(alipayTradeAppPayResponse) }
                    ?.run {
                        Ok("获取预支付参数成功", body)
                    }
                    ?: kotlin.run {
                        log.error(
                            "支付宝App支付(系统)失败",
                        )
                        Fail("支付失败")
                    }
            }

    override fun createText2PicAliOrder(text2PicOrderDto: Text2PicOrderDto): Data<String> {
        val singlePayRecord = SinglePayRecord()
        singlePayRecordService.save(singlePayRecord.apply {
            type = 1
            text = text2PicOrderDto.text
            resolution = text2PicOrderDto.resolution
            style = text2PicOrderDto.style
            num = text2PicOrderDto.num
        })
        return userMemberOrderService.createUserMemberOrder(UserMemberOrderDto().apply {
            BeanUtil.copyProperties(text2PicOrderDto, this)
            payType = PayTypeEnum.ALI_PAY.code
            singlePayRecordId = singlePayRecord.id

        })
            .let {
                Factory.Payment.App().pay(
                    memberService.getNameByMemberId(it.memberId!!),
                    it.orderNum,
                    memberService.getById(text2PicOrderDto.memberId)?.price.toString()
                )
                    .takeIf { alipayTradeAppPayResponse -> ResponseChecker.success(alipayTradeAppPayResponse) }
                    ?.run {
                        Ok("获取文生图预支付参数成功", body)
                    }
                    ?: kotlin.run {
                        log.error(
                            "支付宝App支付(系统)失败",
                        )
                        Fail("支付失败")
                    }
            }
    }

    override fun createPic2PicAliOrder(pic2PicOrderDto: Pic2PicOrderDto): Data<String> {

        val singlePayRecord = SinglePayRecord()
        singlePayRecordService.save(singlePayRecord.apply {
            type = 2
            inputUrl = pic2PicOrderDto.inputUrl
            prompt = pic2PicOrderDto.prompt
            negativePrompt = pic2PicOrderDto.negativePrompt
            style = pic2PicOrderDto.styles
            resultConfig = pic2PicOrderDto.resultConfig
            strength = pic2PicOrderDto.strength
        })

        return userMemberOrderService.createUserMemberOrder(UserMemberOrderDto().apply {
            BeanUtil.copyProperties(pic2PicOrderDto, this)
            payType = PayTypeEnum.ALI_PAY.code
            singlePayRecordId = singlePayRecord.id

        })
            .let {
                Factory.Payment.App().pay(
                    memberService.getNameByMemberId(it.memberId!!),
                    it.orderNum,
                    memberService.getById(pic2PicOrderDto.memberId)?.price.toString()
                )
                    .takeIf { alipayTradeAppPayResponse -> ResponseChecker.success(alipayTradeAppPayResponse) }
                    ?.run {
                        Ok("获取图生图预支付参数成功", body)
                    }
                    ?: kotlin.run {
                        log.error(
                            "支付宝App支付(系统)失败",
                        )
                        Fail("支付失败")
                    }
            }
    }

    override fun createCartoonAliOrder(cartoonOrderDto: CartoonOrderDto): Data<String> {

        val singlePayRecord = SinglePayRecord()
        singlePayRecordService.save(singlePayRecord.apply {
            type = 3
            style = cartoonOrderDto.style
            inputUrl = cartoonOrderDto.inputUrl
        })

        return userMemberOrderService.createUserMemberOrder(UserMemberOrderDto().apply {
            BeanUtil.copyProperties(cartoonOrderDto, this)
            payType = PayTypeEnum.ALI_PAY.code
            singlePayRecordId = singlePayRecord.id

        })
            .let {
                Factory.Payment.App().pay(
                    memberService.getNameByMemberId(it.memberId!!),
                    it.orderNum,
                    memberService.getById(cartoonOrderDto.memberId)?.price.toString()
                )
                    .takeIf { alipayTradeAppPayResponse -> ResponseChecker.success(alipayTradeAppPayResponse) }
                    ?.run {
                        Ok("获取卡通预支付参数成功", body)
                    }
                    ?: kotlin.run {
                        log.error(
                            "支付宝App支付(系统)失败",
                        )
                        Fail("支付失败")
                    }
            }
    }

    override fun wxNotify(xmlData: String): String =
        wxService.parseOrderNotifyResult(xmlData).run {

            log.info("--------------进入到了回调------------------:$xmlData")
            userMemberOrderService.updateMemberPayStatus(outTradeNo, PayTypeEnum.WEI_XIN)
            WxPayNotifyResponse.success("成功")
        }


    override fun aliNotify(request: HttpServletRequest): String {
//        Factory.Payment.Common().takeIf { it.verifyNotify(request.params())}
//            ?.run {
//
//            }
//            ?: kotlin.run {
//                log.error("验证签名失败")
//                "fail"
//            }

        log.info("--------------进入到了回调------------------")
        userMemberOrderService.getUserMemberOrderByOrderNum(request.getParameter("out_trade_no"))
            ?.run {
                userMemberOrderService.updateMemberPayStatus(orderNum!!, PayTypeEnum.ALI_PAY)
            }
        return "success"
    }

}